/*
Copyright (c) [2019年5月1日] [吴超]
[MBT_studio] is licensed under Mulan PSL v2.
You can use this software according to the terms and conditions of the Mulan PSL v2.
You may obtain a copy of Mulan PSL v2 at:
		 http://license.coscl.org.cn/MulanPSL2
THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
See the Mulan PSL v2 for more details.
*/
#include "stdafx.h"
#include "体素数据.h"
#include "节点/socket_utils.h"

#include <节点/插座/list/list数值插座.h>
#include <节点/插座/list/list物体插座.h>
#include <节点/插座/list/list矢量插座.h>



C_体素属性节点::C_体素属性节点(S_设备环境& ctx) : C_节点基类(DEF_取体素属性节点, E_节点类型::e_节点Type_变量) {
	m_Ctx = ctx;
	f_setWName(u"体素属性");

	C_插座基类* socket;
	DEF_创建Vec3_1D插座_I(u"体素");
	DEF_创建Vec3插座_I(u"单元大小", nullptr);

	DEF_创建iVec3插座_O(u"分辨率", nullptr);
	DEF_创建Vec3插座_O(u"最小坐标", nullptr);
	DEF_创建Vec3插座_O(u"单元大小", nullptr);

	DEF_Vec3插座数据(f_get输入插座(2)) = {1,1,1};
}

C_体素属性节点::~C_体素属性节点() {
	
}

bool C_体素属性节点::f_update() {
	return false;
}

std::string C_体素属性节点::DEF_节点编译函数 {
	m_Code = "";
	m_ReleaseCode = "";
	std::string name = f_getName();

	f_su_插座类型切换到连入的插座类型(this, E_插座方向::e_插座Type_输入, 1, E_值类型::e_Type_Vec3_1D);
	auto* socket1 = f_get输入插座(1);
	auto* socket2 = f_get输入插座(2);
	

	auto 分辨率 = name + "_分辨率";
	auto 最小坐标 = name + "_最小坐标";
	auto 单元大小 = name + "_单元大小";
	

	switch (socket1->m_Type) {
		case E_值类型::e_Type_Vec3_1D: {
			m_Code += DEF_S(ivec3)" " + 分辨率 + "{};\n";
			m_Code += DEF_S(vec3)" " + 最小坐标 + "{};\n";
			f_su_切换后端插座类型(this, E_插座方向::e_插座Type_输出, 1, E_值类型::e_Type_iVec3);
			f_su_切换后端插座类型(this, E_插座方向::e_插座Type_输出, 2, E_值类型::e_Type_Vec3);
			break;
		}
		case E_值类型::e_Type_Bounding: {
			f_su_切换后端插座类型(this, E_插座方向::e_插座Type_输入, 2, E_值类型::e_Type_Vec3);
			f_su_切换后端插座类型(this, E_插座方向::e_插座Type_输出, 1, E_值类型::e_Type_iVec3);
			f_su_切换后端插座类型(this, E_插座方向::e_插座Type_输出, 2, E_值类型::e_Type_Vec3);
			
			m_Code += DEF_S(ivec3)" " + 分辨率 + "{};\n";
			m_Code += DEF_S(vec3)" " + 最小坐标 + "{};\n";
			break;
		}
		case E_值类型::e_Type_Bounding_1D: {
			f_su_切换后端插座类型(this, E_插座方向::e_插座Type_输入, 2, E_值类型::e_Type_Vec3_1D);
			f_su_切换后端插座类型(this, E_插座方向::e_插座Type_输出, 1, E_值类型::e_Type_iVec3_1D);
			f_su_切换后端插座类型(this, E_插座方向::e_插座Type_输出, 2, E_值类型::e_Type_Vec3_1D);
			
			m_Code += DEF_S(S_iVec3Array*)" " + 分辨率 + "{};\n";
			m_Code += DEF_S(S_Vec3Array*)" " + 最小坐标 + "{};\n";
			break;
		}
	}
	m_Code += DEF_S(vec3)" " + 单元大小 + "{1,1,1};\n";


	m_Code += "{\n";
	m_Code += socket1->f_构建变量代码(0);
	
	

	switch (socket1->m_Type) {
		case E_值类型::e_Type_Vec3_1D: {
			m_Code += socket2->f_构建变量代码(0);

			m_Code += 分辨率 + " = " + DEF_S(f_core_array_getDim)"((S_Array*)" + socket1->f_getCode(0) + ");\n";
			m_Code += 单元大小 + " = " + DEF_S(f_core_array_getUnitSize)"((S_Array*)" + socket1->f_getCode(0) + ");\n";
			break;
		}
		case E_值类型::e_Type_Bounding: {
			f_su_切换后端插座类型(this, E_插座方向::e_插座Type_输入, 2, E_值类型::e_Type_Vec3);
			f_su_切换后端插座类型(this, E_插座方向::e_插座Type_输出, 1, E_值类型::e_Type_iVec3);
			auto* socket2 = f_get输入插座(2);
			m_Code += socket2->f_构建变量代码(0);

			m_Code += 分辨率 + " = " + DEF_S(f_bound_体素分辨率)"(" + socket1->f_getCode(0) + ", " + socket2->f_getCode(0) + ");\n";
			m_Code += 最小坐标 + " = " + DEF_S(f_geom_包围盒最小坐标)"(" + socket1->f_getCode(0) + ", " + socket2->f_getCode(0) + ");\n";
			m_Code += 单元大小 + " = " + socket2->f_getCode(0) + ";\n";
			break;
		}
		case E_值类型::e_Type_Bounding_1D: {
			f_su_切换后端插座类型(this, E_插座方向::e_插座Type_输入, 2, E_值类型::e_Type_Vec3_1D);
			f_su_切换后端插座类型(this, E_插座方向::e_插座Type_输出, 1, E_值类型::e_Type_iVec3_1D);
			f_su_切换后端插座类型(this, E_插座方向::e_插座Type_输出, 2, E_值类型::e_Type_Vec3_1D);
			auto* socket2 = f_get输入插座(2);
			m_Code += socket2->f_构建变量代码(0);

			m_Code += DEF_S(f_bounds_体素分辨率)"(" + socket1->f_getCode(0) + ", " + socket2->f_getCode(0) + ", " + 分辨率 +");\n";
			m_Code += DEF_S(f_geom_包围盒最小坐标)"(" + socket1->f_getCode(0) + ", " + socket2->f_getCode(0) + ", " + 最小坐标 + ");\n";
			m_Code += 单元大小 + " = " + socket2->f_getCode(0) + ";\n";
			break;
		}
	}
	m_Code += m_ReleaseCode;
	m_Code += "}\n";

	f_get输出插座(1)->f_setCode(分辨率);
	f_get输出插座(2)->f_setCode(最小坐标);
	f_get输出插座(3)->f_setCode(单元大小);
	if (m_区域父节点) {
		m_区域父节点->m_Code += m_Code;
		return "";
	}
	return m_Code;
}

void C_体素属性节点::f_读取(FILE* f) {
	C_节点基类::f_读取(f);

	S_文件块 文件块 = f_file_读取文件块(f);
	if (文件块.m_块类型 == E_节点工程文件块类型::e_工程文件块_节点实例属性) {
		const uint8* 下一次读取数据指针 = 文件块.m_data;

		if (f_file_版本对比(文件块, S_引擎配置::g_低版本号_0, S_引擎配置::g_文件版本号)) {
			//下一次读取数据指针 = f_prop_Load(m_统计类型, 下一次读取数据指针);
		}
	}
	free(文件块.m_data);
}

void C_体素属性节点::f_写入(FILE* f) {
	C_节点基类::f_写入(f);

	auto 文件块 = f_文件块_创建(E_节点工程文件块类型::e_工程文件块_节点实例属性, S_引擎配置::g_文件版本号);
	S_UI8Array* 块 = (S_UI8Array*)f_core_array_new(0, sizeof(uint8));

	//f_prop_Save(m_统计类型, 块);

	f_file_保存文件块(f, 文件块, 块);
}

C_节点基类* f_node_创建体素属性节点(S_设备环境& ctx, C_节点树* 子节点树) {
	return new C_体素属性节点(ctx);
}

C_节点基类* f_node_加载体素属性节点(S_设备环境& ctx, FILE* f) {
	C_体素属性节点* node = new C_体素属性节点(ctx);
	return node;
}

void f_node_保存体素属性节点(C_节点基类* n, FILE* f) {
	C_体素属性节点* node = dynamic_cast<C_体素属性节点*>(n);
}






C_设置体素属性节点::C_设置体素属性节点(S_设备环境& ctx) : C_节点基类(DEF_设置体素属性节点, E_节点类型::e_节点Type_变量) {
	m_Ctx = ctx;
	f_setWName(u"体素属性");

	C_插座基类* socket;
	DEF_创建Vec3_1D插座_I(u"体素");
	DEF_创建Vec3插座_I(u"成员", nullptr);
	
	DEF_创建Vec3_1D插座_O(u"体素", nullptr);

	DEF_Vec3插座数据(f_get输入插座(2)) = { 1,1,1 };

	m_设置类型 = f_alloc_EnumProp(nullptr, {
		{u"单元大小"},
		{u"分辨率"},
	}, u"设置属性成员");
	m_设置类型.m_私有 = true;

}

C_设置体素属性节点::~C_设置体素属性节点() {
	f_prop_Release(m_设置类型);
}

bool C_设置体素属性节点::f_update() {
	return false;
}

std::string C_设置体素属性节点::DEF_节点编译函数 {
	m_Code = "";
	m_ReleaseCode = "";
	std::string name = f_getName();

	//f_su_插座类型切换到连入的插座类型(this, E_插座方向::e_插座Type_输入, 1, E_值类型::e_Type_Vec3_1D);
	switch (f_prop_enum(m_设置类型)) {
		case 0: {
			f_su_切换后端插座类型(this, E_插座方向::e_插座Type_输入, 2, E_值类型::e_Type_Vec3);
			break;
		}
		case 1: {
			f_su_切换后端插座类型(this, E_插座方向::e_插座Type_输入, 2, E_值类型::e_Type_iVec3);
			break;
		}
	}
	auto* socket1 = f_get输入插座(1);
	auto* socket2 = f_get输入插座(2);



	m_Code += "{\n";
	m_Code += socket1->f_构建变量代码(0);
	m_Code += socket2->f_构建变量代码(0);

	switch (f_prop_enum(m_设置类型)) {
		case 0: {
			m_Code += DEF_S(f_core_array_setUnitSize);
			break;
		}
		case 1: {
			m_Code += DEF_S(f_core_array_setDim);
			break;
		}
	}
	m_Code += "((S_Array*)" + socket1->f_getCode(0) + ", " + socket2->f_getCode(0) + ");\n";

	m_Code += m_ReleaseCode;
	m_Code += "}\n";


	f_get输出插座(1)->f_setCode(socket1->f_getCode(0));
	if (m_区域父节点) {
		m_区域父节点->m_Code += m_Code;
		return "";
	}
	return m_Code;
}

void C_设置体素属性节点::f_读取(FILE* f) {
	C_节点基类::f_读取(f);

	S_文件块 文件块 = f_file_读取文件块(f);
	if (文件块.m_块类型 == E_节点工程文件块类型::e_工程文件块_节点实例属性) {
		const uint8* 下一次读取数据指针 = 文件块.m_data;

		if (f_file_版本对比(文件块, S_引擎配置::g_低版本号_0, S_引擎配置::g_文件版本号)) {
			下一次读取数据指针 = f_prop_Load(m_设置类型, 下一次读取数据指针);
		}
	}
	free(文件块.m_data);
}

void C_设置体素属性节点::f_写入(FILE* f) {
	C_节点基类::f_写入(f);

	auto 文件块 = f_文件块_创建(E_节点工程文件块类型::e_工程文件块_节点实例属性, S_引擎配置::g_文件版本号);
	S_UI8Array* 块 = (S_UI8Array*)f_core_array_new(0, sizeof(uint8));

	f_prop_Save(m_设置类型, 块);

	f_file_保存文件块(f, 文件块, 块);
}

C_节点基类* f_node_创建设置体素属性节点(S_设备环境& ctx, C_节点树* 子节点树) {
	return new C_设置体素属性节点(ctx);
}

C_节点基类* f_node_加载设置体素属性节点(S_设备环境& ctx, FILE* f) {
	C_设置体素属性节点* node = new C_设置体素属性节点(ctx);
	return node;
}

void f_node_保存设置体素属性节点(C_节点基类* n, FILE* f) {
	C_设置体素属性节点* node = dynamic_cast<C_设置体素属性节点*>(n);
}




